package com.jorenwu.asymmetric;

import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StringReader;
import java.math.BigInteger;

public class MainP
{

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{

		// String[] num = { "343312092563", "883357091", "5" };
		// // use Fermat algorism to prime-test num[i]
		// for (int i = 0; i < num.length; i++)
		// {
		// BigInteger bigNum = new BigInteger(num[i]);
		//
		// PrimeTest pt = new FermatPrimeTest();
		// if (pt.primeTest(bigNum, 20))
		// System.out.println("it is a prime number!");
		// else
		// System.out.println("it is a composite number!");
		// }
		// // use Pratt algorism to prime-test num[i]
		// for (int i = 0; i < num.length; i++)
		// {
		// BigInteger bigNum = new BigInteger(num[i]);
		// PrimeTest pt = new PrattPrimeTest();
		// if (pt.primeTest(bigNum, 20))
		// System.out.println("it is a prime number!");
		// else
		// System.out.println("it is a composite number!");
		// }
		// // use Solovay-Strassen algorism to prime-test num[i]
		// for (int i = 0; i < num.length; i++)
		// {
		// BigInteger bigNum = new BigInteger(num[i]);
		// PrimeTest pt = new SolovayStrassenPrimeTest();
		// if (pt.primeTest(bigNum, 20))
		// System.out.println("it is a prime number!");
		// else
		// System.out.println("it is a composite number!");
		// }
		// //use Miller-Rabin algorism to prime-test num[i]
		//
		// for (int i = 0; i < num.length; i++)
		// {
		// BigInteger bigNum = new BigInteger(num[i]);
		// PrimeTest pt = new MillerRabinPrimeTest();
		// if (pt.primeTest(bigNum, 20))
		// System.out.println("it is a prime number!");
		// elsejorenwu
		// System.out.println("it is a composite number!");
		// }
		//
		// // use Shanks algorism to factorize num[i]
		long p = 0, e = 0, g = 0, u = 0;
		// // input format: 809;3;525
		// System.out
		// .println("please input the p;g;u for logarithm factorizatioin:");
		// try
		// {
		// BufferedReader bin = new BufferedReader(new InputStreamReader(
		// System.in));
		// String line = bin.readLine();
		// StringTokenizer st = new StringTokenizer(line, ";", false);
		// while (st.hasMoreTokens() != false)
		// {
		// p = Long.valueOf(st.nextToken());
		// g = Long.valueOf(st.nextToken());
		// u = Long.valueOf(st.nextToken());
		// }
		// } catch (Exception ex)
		// {
		// ex.printStackTrace();
		// }
		// Factorization sf = new ShanksFactorization(p, g, u);
		// System.out.println(sf.factorize());
		// // use Pohlig-Hellman algorism to factorize num[i]
		// // input format:
//		 System.out.println("please input the p;e;g;u for logarithm factorizatioin:");
//		 try
//		 {
//		 BufferedReader bin = new BufferedReader(new InputStreamReader(
//		 System.in));
//		 String line = bin.readLine();
//		 StringTokenizer st = new StringTokenizer(line, ";", false);
//		 while (st.hasMoreTokens() != false)
//		 {
//		 p = Long.valueOf(st.nextToken());
//		 g = Long.valueOf(st.nextToken());
//		 u = Long.valueOf(st.nextToken());
//		 e = Long.valueOf(st.nextToken());
//		 }
//		 } catch (Exception ex)
//		 {
//		 ex.printStackTrace();
//		 }
//		 Factorization phf = new PohligHellmanFactorization(p, e, g, u);
//		 System.out.println(phf.factorize());
		//
		// // calculate a[i] to be Mersenne numbers
		// int a[] = { 23, 29, 37, 41, 43, 47, 53, 59 };
		// for (int i = 0; i < a.length; i++)
		// System.out.println((long) Math.pow(2, a[i]) - 1);
		// calculate b[i] to be Fermat numbers
		// int b[] = { 1, 2, 3, 4, 5, 6, 7 };
		// for (int i = 0; i < b.length; i++)
		// {
		// System.out.println(BaseCalculator.TWO.pow(
		// BaseCalculator.TWO.pow(b[i]).intValue()).toString());
		// }
		// about BaseCalculator basic functions' test
		 BaseCalculator bc = new BaseCalculator();
		// System.out.println(bc.factoria(new BigInteger("4")).toString());
		 System.out.println(bc.Pollard((new BigInteger("23016001"))).toString());
		 System.out.println(bc.Pollard((new BigInteger("883357091"))).toString());
		 System.out.println(bc.Pollard((new BigInteger("343312092563"))).toString());
		// System.out.println(bc.sqrt(new BigInteger("169")).toString());// the
		// sqrted result should be 13
		 // use RSAEngine algorism
//		 BigInteger input=new BigInteger("43918749387198573913984793");
		System.out.println("test for RSA...");
		String str1 = "i am a student from Peking Universicty!";
		int nbits = 1024; // 512 < nbits < 512*k
		// boolean forEncryption=true;
		RSAengine re = new RSAengine(nbits);
		re.keyGenerate();
		// re.setForEncryption(forEncryption);
		try
		{
			StringReader br = new StringReader(str1);
			BufferedOutputStream bos = new BufferedOutputStream(
					new FileOutputStream("jorenwu.code"));
			re.blockEncrypto(br, bos);
			FileInputStream fis = new FileInputStream("jorenwu.code");
			BufferedWriter bw = new BufferedWriter(new FileWriter(
					"jorenwu.decode"));
			re.blockDecrypto(bw, fis);
		} catch (Exception ex)
		{
			ex.printStackTrace();
		}
		// re.setInput(input);
		// re.saveKey("jorenwu");
		// re.getFilePrivateKey("jorenwu.private");
		// re.getFilePublicKey("jorenwu.public");
		System.out.println((re.getP()).toString());
		System.out.println((re.getQ()).toString());
		System.out.println((re.getPublicKey()).toString());
		System.out.println((re.getPrivateKey()).toString());
		System.out.println((re.getN()).toString());
		// System.out.println(re.numProcess());
		// re.setForEncryption(false);
		// System.out.println(re.numProcess());
		// //use EIGamal test
		System.out.println("test for EIGamal...");
		String str2 = "i am a student from Peking University!";
		EIGamalengine ei = new EIGamalengine(nbits);
		ei.keyGenerate();
		System.out.println((ei.getP()).toString());
		System.out.println((ei.getG()).toString());
		System.out.println((ei.getX()).toString());
		System.out.println((ei.getY()).toString());
		try
		{
			StringReader br = new StringReader(str2);
			ObjectOutputStream bos = new ObjectOutputStream(
					new FileOutputStream("jorenwuE.code"));
			// BufferedOutputStream bos=new BufferedOutputStream(new
			// FileOutputStream("jorenwuE.code"));
			ei.blockEncrypto(br, bos);
			// FileInputStream fis=new FileInputStream("jorenwuE.code");
			ObjectInputStream fis = new ObjectInputStream(new FileInputStream(
					"jorenwuE.code"));
			BufferedWriter bw = new BufferedWriter(new FileWriter(
					"jorenwuE.decode"));
			ei.blockDecrypto(bw, fis);
		} catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}
}
